package com.inspur.edp.bef.bemanager.dependency;

import com.inspur.edp.bef.bemanager.util.BefFileUtil;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.lcm.metadata.api.service.FileService;

import com.inspur.edp.lcm.metadata.common.FileServiceImp;
import com.inspur.edp.lcm.metadata.common.logging.MvnStreamConsumer;
import com.inspur.edp.lcm.metadata.core.exception.MvnExceptionHandler;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import com.inspur.edp.lcm.metadata.devcommon.ManagerUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.utils.cli.CommandLineException;
import org.codehaus.plexus.util.StringUtils;

@Slf4j
public class ManageProjectDependencyUtil {
	private FileService fileService;
	private String mavenHomePath;

	private final DefaultInvoker invoker;

	private final InvocationRequest request;

	private final MvnStreamConsumer mvnStreamConsumer;

	private String errorMessage;

	private ManageProjectDependencyUtil() {
		invoker = new DefaultInvoker();
		request = new DefaultInvocationRequest();
		mvnStreamConsumer = new MvnStreamConsumer();
	}

	public static ManageProjectDependencyUtil getInstance() {
		return new ManageProjectDependencyUtil();
	}


	ModifyPomUtil modifyPomUtil = ModifyPomUtil.getInstance();

	public void addDefaultProjectDependency(String javaProjPath) {
//		String currentJarPath = getServerPath() + "\\platform\\common\\libs";
		String absoluteProjPath = getAbsolutePath(javaProjPath);
		// 添加基本依赖 cef-api等
		addProjectDependency(absoluteProjPath, null, modifyPomUtil.getDefaultDependency());
		// 扩展依赖-jackson等
		modifyPomUtil.modifyPom(absoluteProjPath, modifyPomUtil.getExtendDependency());
		// 添加sgf依赖
		modifyPomUtil.modifyPom(absoluteProjPath,modifyPomUtil.getSgfExtendDependency());
	}

	public void addProjectDependency(String projectPath, String currentJarPath, ArrayList<MavenDependency> dependencyArrayList) {
		// 安装jar包到maven仓库
		installPackage(projectPath, currentJarPath, dependencyArrayList);
		// 修改pom文件
		modifyPomUtil.modifyPom(projectPath, dependencyArrayList);
	}

	/**
	 * 安装{projectPath}jar包到maven仓库
	 *
	 * @param projectPath
	 * @param currentJarPath
	 * @param dependencyArrayList
	 */
	public void installPackage(String projectPath, String currentJarPath,
	                           ArrayList<MavenDependency> dependencyArrayList) {
		// 组装命令
//		String command = String.format("cmd /c cd %s", projectPath);
//		Process process = null;
//		String command = null;
		String command = "";
		if (currentJarPath != null && !currentJarPath.isEmpty()) {
			String addDependencyCommand = "mvn install:install-file -DgroupId=%1$s " +
					"-DartifactId=%2$s -Dversion=%3$s -Dpackaging=jar -Dfile=%4$s";
			for (MavenDependency dependency : dependencyArrayList) {
				String addCommand = String.format(addDependencyCommand, dependency.getGroupId(),
						dependency.getArtifactId(), dependency.getVersion(), getPathString(String.format(currentJarPath + "\\%1$s",
								dependency.getFile())));
				command = command.concat(" && " + addCommand);
			}
			exeMavenCommand(projectPath,null,command);
		}
//		BefFileUtil.excecuteCommand(process, command, "添加bef相关jar包");
	}

	// region 私有方法

	private String getServerPath() {
		return BefFileUtil.getServerPath();
	}

	private String getPathString(String path) {
		return BefFileUtil.getAbsolutePathString(path);
	}

	private void log(String message) {
		BefFileUtil.log(message);
	}

	private FileService getFileService() {
		if (fileService == null) {
			fileService = BefFileUtil.getService(FileService.class);
		}
		return fileService;
	}

	private String getAbsolutePath(String relativePath) {
//		String devPath = getFileService().getDevRootPath();
		String devPath = ManagerUtils.getDevRootPath();

		return Paths.get(devPath).resolve(relativePath).toString();
	}

	public  boolean exeMavenCommand(String javaCodePath, String mavenPath, String goal) {
		initInvoker();

		invoker.setWorkingDirectory(new File(javaCodePath));

		List<String> goals = handleGoul(goal, mavenPath);
		request.setGoals(goals);

		try {
			mvnStreamConsumer.setExceptionString("");
			InvocationResult result = invoker.execute(request);
			int resultNum = result.getExitCode();
			if (resultNum == 0) {
				return true;
			}

			if (resultNum == 1) {
				final String exceptionString = mvnStreamConsumer.getExceptionString();
				if (!exceptionString.isEmpty()) {
					MvnExceptionHandler mvnExceptionHandler = new MvnExceptionHandler();
					errorMessage = "";
					errorMessage = mvnExceptionHandler.handleMessage(exceptionString);
					errorMessage = errorMessage.isEmpty() ? "maven编译失败，具体错误请参考日志服务[ERROR]部分" : errorMessage;
				}

				CommandLineException executionException = result.getExecutionException();
				if (executionException != null) {
					throw executionException;
				}
				return false;
			}
		} catch (Exception e) {
			log.error("执行maven命令失败",e.getMessage());
		}
		return false;
	}

	private void initInvoker() {
		initMavenHomePath();
		invoker.setMavenHome(new File(mavenHomePath));
		request.setOutputHandler(mvnStreamConsumer).setBatchMode(true);
	}

	private void initMavenHomePath() {
		if (!StringUtils.isEmpty(mavenHomePath)) {
			return;
		}

		if (System.getenv("MAVEN_HOME") != null) {
			mavenHomePath = System.getenv("MAVEN_HOME");
		} else if (System.getenv("M2_HOME") != null){
			mavenHomePath = System.getenv("M2_HOME");

			invoker.setMavenHome( new File(System.getenv("M2_HOME")));
		} else {
			String systemPath = System.getenv("Path");
			if (systemPath != null) {
				String[] paths = systemPath.split("\\;");
				for (String path : paths) {
					if (path.contains("maven")) {
						mavenHomePath = path.substring(0,path.length()-4);
					}
				}
			}
		}
		if (StringUtils.isEmpty(mavenHomePath)) {
			throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0053);
		}


	}

	private List<String> handleGoul(String goal,String mavenPath) {
		List<String> goals = new ArrayList<>();

		StringBuilder goalSb = new StringBuilder(goal);
		String settingsPath = mavenPath + File.separator + "config" + File.separator + "settings.xml";
		FileServiceImp fileService=new FileServiceImp();
		if (fileService.isFileExist(settingsPath)) {
			goalSb.append(" -s ").append(settingsPath);
		} else {
			log.warn("配置文件" + settingsPath + "不存在，使用默认settings.xml配置");
		}

		goals.add(goalSb.toString());
		return goals;
	}
	// endregion
}
